﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

using mvcForum.Core;
using mvcForum.Core.Interfaces;
using mvcForum.Core.Helpers;

namespace mvcForum.Web.Services {

	public class NTFSAttachmentStorage : IAttachmentStorage {
		private readonly String physicalRoot;
		private readonly String webRoot;

		private const Int32 bufferSize = 4096;

		public NTFSAttachmentStorage(String physicalRoot, String webRoot) {
			this.physicalRoot = physicalRoot;
			this.webRoot = webRoot;
		}

		public String CreateAttachment(Attachment attachment, Stream inputStream, String contentType) {
			IEnumerable<String> path = this.GeneratePath(attachment.Post).Concat(new String[] { attachment.Id.ToString() });

			String ntfsPath = Path.Combine(this.physicalRoot, (this.Root.StartsWith("/") ? this.Root.Substring(1) : this.Root));
			foreach (String part in path) {
				ntfsPath = Path.Combine(ntfsPath, part);
				if (!Directory.Exists(ntfsPath)) {
					Directory.CreateDirectory(ntfsPath);
				}
			}

			String fullPath = Path.Combine(ntfsPath, attachment.Filename);
			using (MemoryStream memStream = new MemoryStream()) {
				inputStream.CopyTo(memStream);
				File.WriteAllBytes(fullPath, memStream.ToArray());
			}

			return String.Format("{0}/{1}", this.Root, String.Join("/", path));
		}

		public void DeleteAttachment(Attachment attachment) {
			IEnumerable<String> path = this.GeneratePath(attachment.Post).Union(new String[] { attachment.Id.ToString() });

			String ntfsPath = Path.Combine(this.physicalRoot, String.Join("\\", path));
			try {
				Directory.Delete(ntfsPath);
			}
			catch {
				// TODO: Log it somewhere!
			}
		}

		public void DeleteAttachments(Post post) {
			IEnumerable<String> path = this.GeneratePath(post);

			String ntfsPath = Path.Combine(this.physicalRoot, String.Join("\\", path));
			try {
				Directory.Delete(ntfsPath, true);
			}
			catch {
				// TODO: Log it somewhere!
			}
		}

		private String[] GeneratePath(Post post) {
			return PathHelper.GetPath(12, post.Id);
		}

		public String Root {
			get {
				return webRoot;
			}
		}
	}
}